package lab_1;

import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.Naming;
import java.net.MalformedURLException;
import java.util.Date;

/**
 *
 * @author grp02 - Pascal Charreix and Meike Paetz
 *
 * This is the Implementation of the Manager
 */
public class ManagerImpl extends UnicastRemoteObject implements AgencyManager, SmartToursManager {

    private HPackageImpl[] listPackages;
    private final int maxSize = 5;

    /**
     * Manager Implementation constructor, initialising the list of Packages
     */
    public ManagerImpl() throws RemoteException {
        int i = 0;
        listPackages = new HPackageImpl[maxSize];
        while (i < maxSize) {
            listPackages[i] = null;
            i++;
        }
    }

    /**
     * Return one package using the RMI registry
     */
    @Override
    public HPackage getHolidayPackage(int id) throws RemoteException {
        HPackage a = null;
        try {
            a = (HPackage) Naming.lookup(Integer.toString(id));
        } catch (Exception e) {
        }
        return a;
    }

    /**
     * creates Holiday Package
     */
    @Override
    public int createHolidayPackage(String Country, Date Start, Date End, String HotelName, int HotelStars, String FlightOperator, float Price) throws RemoteException {
        System.out.print("Create new Holiday Package... ");
        HPackage newPackage = new HPackageImpl(Country, Start, End, HotelName, HotelStars, FlightOperator, Price);
        listPackages[newPackage.getReservationNbr()] = (HPackageImpl) newPackage;
        try {
            Naming.rebind(Integer.toString(newPackage.getReservationNbr()), newPackage);
        } catch (RemoteException a) {
            System.err.println("if registry could not be contacted\n" + a.getMessage());
        } catch (MalformedURLException a) {
            System.out.println("if the name is not an appropriately formatted URL\n" + a.getMessage());
        }
        System.out.println("done.");
        return newPackage.getReservationNbr();
    }

    /**
     *
     * deletes Holiday Package
     */
    @Override
    public boolean deleteHolidayPackage(int id) throws RemoteException, NotBoundException {
        System.out.print("Delete Holiday Package " + id + "... ");
        try {
            Naming.unbind(Integer.toString(id));
            listPackages[id] = null;
        } catch (RemoteException a) {
            System.err.println("if registry could not be contacted\n" + a.getMessage());
        } catch (MalformedURLException a) {
            System.out.println("if the name is not an appropriately formatted URL\n" + a.getMessage());
        }
        System.out.println("done.");
        return true;
    }

    /**
     *
     * finds Holiday Package by country
     */
    @Override
    public HPackage findByCountry(String Country) throws RemoteException {
        int i = 0;
        while (i < maxSize) {
            if (listPackages[i] != null && !listPackages[i].isLocked() && !listPackages[i].isReserved() && listPackages[i].getCountry().equals(Country)) {
                listPackages[i].lock();
                return listPackages[i];
            }
            i++;
        }
        return null;
    }

    /**
     *
     * finds Holiday Package by arrival date
     */
    @Override
    public HPackage findByDateAfter(Date Start) throws RemoteException {
        int i = 0;
        while (i < maxSize) {
            if (listPackages[i] != null && !listPackages[i].isLocked() && !listPackages[i].isReserved() && listPackages[i].getJourneyDates()[0].compareTo(Start) >= 0) {
                listPackages[i].lock();
                return listPackages[i];
            }
            i++;
        }
        return null;
    }

    /**
     *
     * finds Holiday Package by departure date
     */
    @Override
    public HPackage findByDateBefore(Date End) throws RemoteException {
        int i = 0;
        while (i < maxSize) {
            if (listPackages[i] != null && !listPackages[i].isLocked() && !listPackages[i].isReserved() && listPackages[i].getJourneyDates()[1].compareTo(End) <= 0) {
                listPackages[i].lock();
                return listPackages[i];
            }
            i++;
        }
        return null;
    }

    /**
     *
     * finds Holiday Package by exact departure and arrival date
     */
    @Override
    public HPackage findByDate(Date Start, Date End) throws RemoteException {
        int i = 0;
        while (i < maxSize) {
            if (listPackages[i] != null && !listPackages[i].isLocked() && !listPackages[i].isReserved() && listPackages[i].getJourneyDates()[0].compareTo(Start) >= 0 && listPackages[i].getJourneyDates()[1].compareTo(End) <= 0) {
                listPackages[i].lock();
                return listPackages[i];
            }
            i++;
        }
        return null;
    }

    /**
     *
     * finds Holiday Package by hotel name
     */
    @Override
    public HPackage findByHotelName(String Name) throws RemoteException {
        int i = 0;
        while (i < maxSize) {
            if (listPackages[i] != null && !listPackages[i].isLocked() && !listPackages[i].isReserved() && listPackages[i].getHotelName().equals(Name)) {
                listPackages[i].lock();
                return listPackages[i];
            }
            i++;
        }
        return null;
    }

    /**
     *
     * finds Holiday Package by amount of hotel stars
     */
    @Override
    public HPackage findByHotelStars(int Stars) throws RemoteException {
        int i = 0;
        while (i < maxSize) {
            if (listPackages[i] != null && !listPackages[i].isLocked() && !listPackages[i].isReserved() && listPackages[i].getHotelStars() == Stars) {
                listPackages[i].lock();
                return listPackages[i];
            }
            i++;
        }
        return null;
    }

    /**
     *
     * finds Holiday Package by its exact price
     */
    @Override
    public HPackage findByPrice(float Price) throws RemoteException {
        int i = 0;
        while (i < maxSize) {
            if (listPackages[i] != null && !listPackages[i].isLocked() && !listPackages[i].isReserved() && listPackages[i].getPrice() == Price) {
                listPackages[i].lock();
                return listPackages[i];
            }
            i++;
        }
        return null;
    }

    /**
     *
     * finds Holiday Package by a range of the price
     */
    @Override
    public HPackage findByPrice(float Mini, float Maxi) throws RemoteException {
        int i = 0;
        while (i < maxSize) {
            if (listPackages[i] != null && !listPackages[i].isLocked() && !listPackages[i].isReserved() && listPackages[i].getPrice() >= Mini && listPackages[i].getPrice() <= Maxi) {
                listPackages[i].lock();
                return listPackages[i];
            }
            i++;
        }
        return null;
    }

    /**
     *
     * finds Holiday Package by exact flight operator
     */
    @Override
    public HPackage findByFlightOperator(String Name) throws RemoteException {
        int i = 0;
        while (i < maxSize) {
            if (listPackages[i] != null && !listPackages[i].isLocked() && !listPackages[i].isReserved() && listPackages[i].getFlightOperator().equals(Name)) {
                listPackages[i].lock();
                return listPackages[i];
            }
            i++;
        }
        return null;
    }

    /**
     *
     * finds Holiday Package by its reservation number
     */
    @Override
    public HPackage findByReservationNumber(int Reservation) throws RemoteException {
        int i = 0;
        while (i < maxSize) {
            if (listPackages[i] != null && listPackages[i].getReservationNbr() == Reservation) {
                listPackages[i].lock();
                return listPackages[i];
            }
            i++;
        }
        return null;
    }
}
